package com.zdkj.subway.stm.util;

import cn.hutool.core.date.DateUtil;
import lombok.experimental.UtilityClass;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.time.*;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

/**
 * @author Gofe
 * @version 1.0
 * @project subway
 * @package com.zdkj.subway.stm.util
 * @createDate 2020/2/18 6:35
 * @modfiyDate
 * @function 时间转换工具
 */
@UtilityClass
public class DateUtilStm {
	
	private static String DATA_FORMAT_DATA_SHORT_SYMBOL_X = "yyyy-MM-dd";
	private static String DATA_FORMAT_DATA_SHORT_SYMBOL_Y= "yyyy-MM-dd HH:mm:ss";
    public Date asDate(LocalDateTime localDateTime) {
        return Date.from(localDateTime.atZone(ZoneId.systemDefault()).toInstant());
    }

    public String asDateString(LocalDateTime localDateTime) {
        return null == localDateTime ? "" : DateUtil.formatDate(asDate(localDateTime));
    }

    /**
     * 计算传入日期的前一天
     *
     * @param localDateTime
     * @return
     */
    public String asPreDateString(LocalDateTime localDateTime) {
        return null == localDateTime ? "" : DateUtil.formatDate(asDate(localDateTime.plusDays(-1)));
    }


    public LocalDateTime asLocalDateTime(Date date) {
        return Instant.ofEpochMilli(date.getTime()).atZone(ZoneId.systemDefault()).toLocalDateTime();
    }

    /**
     * 根据开始时间和结束时间计算天数
     * @param start
     * @param end
     * @return
     */
    public Integer getDayInterval(Date start, Date end){
        final long nd = 1000 * 24 * 60 * 60;
        Date startDay = new Date(start.getTime() - start.getTime() % nd);
        Date endDay = new Date(end.getTime() - end.getTime() % nd);
        return (int)((endDay.getTime() - startDay.getTime())/nd);
    }

    public Date LocalDateToUdate(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        java.util.Date date = Date.from(instant);
        return date;
    }
    public String localDateToString(LocalDate localDate) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String dateStr = localDate.format(fmt);
        return dateStr;
    }

	 public String localDateToString(LocalDate localDate,String format) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(format);
        String dateStr = localDate.format(fmt);
        return dateStr;
    }
    public LocalDate stringTolocalDate(String date,String format) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern(format);
        LocalDate date2 = LocalDate.parse(date, fmt);
        return date2;
    }

    public LocalDate stringTolocalDate(String date) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDate date2 = LocalDate.parse(date, fmt);
        return date2;
    }


    /**
     * 获得指定时间前几天的日期
     * @param i 天数
     * @return
     */
    public static String getBeforeDayDate(Date date,int i){
    	 Calendar calendar = Calendar.getInstance();
         calendar.setTime(date);
         calendar.add(Calendar.DAY_OF_MONTH,-i);
         Date time = calendar.getTime();
         SimpleDateFormat dff = new SimpleDateFormat("yyyy-MM-dd");
         return dff.format(time);
       
    }
    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param form
     *          开始时间
     * @param to
     *          结束时间
     * @return
     *          相差天数
     */
    public static int differentDays(Date form, Date to) {
        return (int) ((to.getTime() - form.getTime()) / (1000*3600*24));
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param form
     *          开始时间
     * @param to
     *          结束时间
     * @return
     *          相差小时数
     */
    public static int differentHours(Date form, Date to) {
        return (int) ((to.getTime() - form.getTime()) / (1000*3600));
    }

    /**
     * 通过时间秒毫秒数判断两个时间的间隔
     * @param form
     *          开始时间
     * @param to
     *          结束时间
     * @return
     *          相差分钟数
     */
    public static int differentMinute(Date form, Date to) {
        return (int) ((to.getTime() - form.getTime()) / (1000*60));
    }

    /**
     * 判断两个时间相差多少个月
     * @param form
     *          开始时间
     * @param to
     *          结束时间
     * @return
     *          相差月数
     */
    public static int differentMonth(Date form, Date to){
        Calendar bef = Calendar.getInstance();
        Calendar aft = Calendar.getInstance();
        bef.setTime(form);
        aft.setTime(to);
        int result = aft.get(Calendar.MONTH) - bef.get(Calendar.MONTH);
        int month = (aft.get(Calendar.YEAR) - bef.get(Calendar.YEAR)) * 12;
        return Math.abs(month + result);
    }

    /**
     * 把日期格式化为字符串
     * @param date
     *          日期
     * @param format
     *          格式
     * @return
     *          返回格式化之后的字符串
     */
    public static String dateToString(Date date, String format){
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        return dateFormat.format(date);
    }

    /**
     * 把日期格式化为字符串
     * @param date
     *          日期
     * @param format
     *          格式
     * @return
     *          返回格式化之后的字符串
     */
    public static Date stringToDate(String date,String format){
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 通过传入的日期加指定的天数
     * @param date
     *          日期
     * @param day
     *          天数
     * @return
     *          相加后的天数
     */
    public static Date getNextDay(Date date,int day){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.DAY_OF_YEAR,day);
        return calendar.getTime();
    }

    /**
     * 通过传入的日期加指定的分钟数
     * @param date
     *          日期
     * @param minute
     *          天数
     * @return
     *          相加后的天数
     */
    public static Date getNextMinute(Date date,int minute){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MINUTE, minute);
        return calendar.getTime();
    }

    /**
     * 通过传入的日期加指定的天数
     * @param date
     *          日期
     * @param day
     *          天数
     * @return
     *          相加后的天数
     */
    public static String getNextDay(String date ,int day,String format){
        return dateToString(getNextDay(stringToDate(date,format),day),format);
    }

    /**
     * 通过传入的日期加指定的年数
     * @param date
     *          日期
     * @param year
     *          年数
     * @return
     *          计算后的日期
     */
    public static Date getNextYear(Date date,int year){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.YEAR,year);
        return calendar.getTime();
    }
    /**
     * 通过传入的日期加指定的月数
     * @param date
     *          日期
     * @param month
     *          月数
     * @return
     *          计算后的日期
     */
    public static Date getNextMonth(Date date,int month){
        Calendar calendar = Calendar.getInstance();
        calendar.setTime(date);
        calendar.add(Calendar.MONTH,month);
        return calendar.getTime();
    }


    /**
     * 获取当前的时间
     * @return
     *          返回当前的时间
     */
    public static Date getNowDate(){
        return new Date();
    }

    /**
     * 获取当前的时间（yyyy-MM-dd）
     * @return
     *          返回当前的时间
     */
    public static String getNowDayString(){
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATA_FORMAT_DATA_SHORT_SYMBOL_X);
        return dateFormat.format(getNowDate());
    }
    /**
     * 获取当前的时间（yyyy-MM-dd HH:mm:ss）
     * @return
     *          返回当前的时间
     */
    public static String getNowTime(){
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATA_FORMAT_DATA_SHORT_SYMBOL_Y);
        return dateFormat.format(getNowDate());
    }

    /**
     * 获取当前的时间
     * @return
     *          返回当前的时间
     */
    public static Date getNowDayDate(){
        SimpleDateFormat dateFormat = new SimpleDateFormat(DATA_FORMAT_DATA_SHORT_SYMBOL_X);
        return stringToDate(dateFormat.format(getNowDate()),DATA_FORMAT_DATA_SHORT_SYMBOL_X);
    }
     /**
     * 获得某天23:59:59点时间
     * @return
     */
    public static Date getTimesnight(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 23);
        cal.set(Calendar.SECOND, 59);
        cal.set(Calendar.MINUTE, 59);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * 获得某天0点时间
     * @return
     */
    public static Date getTimesmorning(Date date) {
        Calendar cal = Calendar.getInstance();
        cal.setTime(date);
        cal.set(Calendar.HOUR_OF_DAY, 0);
        cal.set(Calendar.SECOND, 0);
        cal.set(Calendar.MINUTE, 0);
        cal.set(Calendar.MILLISECOND, 0);
        return cal.getTime();
    }

    /**
     * @Description 是否为当天24h内
     * @author guo
     * @param inputJudgeDate 要判断是否在当天24h内的时间
     * @return
     * boolean
     */
    public static boolean isToday(Date inputJudgeDate) {
        boolean flag = false;
        //获取当前系统时间
        long longDate = System.currentTimeMillis();
        Date nowDate = new Date(longDate);
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String format = dateFormat.format(nowDate);
        String subDate = format.substring(0, 10);
        //定义每天的24h时间范围
        String beginTime = subDate + " 00:00:00";
        String endTime = subDate + " 23:59:59";
        Date paseBeginTime = null;
        Date paseEndTime = null;
        try {
            paseBeginTime = dateFormat.parse(beginTime);
            paseEndTime = dateFormat.parse(endTime);

        } catch (ParseException e) {
             e.printStackTrace();
        }
        if(inputJudgeDate.after(paseBeginTime) && inputJudgeDate.before(paseEndTime)) {
            flag = true;
        }
        return flag;
    }

    /**
     * 把日期格式化为字符串
     * @param date
     *          日期
     * @return
     *          返回格式化之后的字符串
     */
    public static Date stringToDateFormat(String date){
        String format = "yyyy-MM-dd HH:mm:ss";
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 把日期格式化为字符串
     * @param date
     *          日期
     * @return
     *          返回格式化之后的字符串
     */
    public static Date stringToDate(String date){
        String format = "yyyy-MM-dd";
        SimpleDateFormat dateFormat = new SimpleDateFormat(format);
        try {
            return dateFormat.parse(date);
        } catch (ParseException e) {
            return null;
        }
    }

    /**
     * 时间戳转date
     * @return
     */
    public static Date timeToDate (Long time) {
        //时间戳转化为Sting或Date
        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String d = format.format(time);
        Date date= null;
        try {
            date = format.parse(d);
            return date;
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 日期string类型转LocalDate
     * @param localDate
     * @return
     */
    public LocalDate LocalDateToString(String localDate) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        LocalDate localDateStr = LocalDate.parse(localDate,fmt);
        return localDateStr;
    }




    /**
     * Timestamp转LocalDateTime
     * @param timestamp
     * @return
     */
    public LocalDateTime TimestampToLocalDateTime(Long timestamp) {
        LocalDateTime localDateTime = Instant.ofEpochMilli(timestamp).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();
        return localDateTime;
    }

    /**
     * 日期LocalDateTime类型转string
     * @param localDateTime
     * @return
     */
    public String LocalDateTimeToString(LocalDateTime localDateTime) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        String dateStr = localDateTime.format(fmt);
        return dateStr;
    }

    /**
     * 日期LocalDate类型转string
     * @param localDate
     * @return
     */
    public String LocalDateTrunString(LocalDate localDate) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String dateStr = localDate.format(fmt);
        return dateStr;
    }


    /**
     * LocalDate转Date
     * @param localDate
     * @return
     */
    public static Date localDate2Date(LocalDate localDate) {
        ZonedDateTime zonedDateTime = localDate.atStartOfDay(ZoneId.systemDefault());
        return Date.from(zonedDateTime.toInstant());
    }

    /**
     * 日期string类型转LocalDateTime
     * @param localDateTime
     * @return
     */
    public LocalDateTime LocalDateTimeToString(String localDateTime) {
        DateTimeFormatter fmt = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
        LocalDateTime localDateStr = LocalDateTime.parse(localDateTime,fmt);
        return localDateStr;
    }

    /**
     * 检验日期格式是否正确
     * @param dttm
     * @param
     * @return
     */
    public boolean isDate(String dttm,String format) {
        if (dttm == null || dttm.isEmpty() || format == null || format.isEmpty()) {
            return false;
        }

        if (format.replaceAll("'.+?'", "").indexOf("y") < 0) {
            format += "/yyyy";
            DateFormat formatter = new SimpleDateFormat("/yyyy");
            dttm += formatter.format(new Date());
        }

        DateFormat formatter = new SimpleDateFormat(format);
        formatter.setLenient(false);
        ParsePosition pos = new ParsePosition(0);
        Date date = formatter.parse(dttm, pos);

        if (date == null || pos.getErrorIndex() > 0) {
            return false;
        }
        if (pos.getIndex() != dttm.length()) {
            return false;
        }

        if (formatter.getCalendar().get(Calendar.YEAR) > 9999) {
            return false;
        }

        return true;
    }


    /**
     * 根据开始时间和结束时间返回时间段内的时间集合
     *
     * @param beginDate
     * @param endDate
     * @return List
     * @throws ParseException
     */
    public static List<String> getDatesBetweenTwoDate(String beginDate, String  endDate) throws ParseException {

        //格式转换
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        List<String> lDate = new ArrayList<>();
        lDate.add(beginDate);// 把开始时间加入集合
        if(beginDate.equals(endDate)){
            return lDate;
        }
        Calendar cal = Calendar.getInstance();
        // 使用给定的 Date 设置此 Calendar 的时间
        cal.setTime(sdf.parse(beginDate));
        boolean bContinue = true;
        while (bContinue) {
            // 根据日历的规则，为给定的日历字段添加或减去指定的时间量
            cal.add(Calendar.DAY_OF_MONTH, 1);
            // 测试此日期是否在指定日期之后
            if (sdf.parse(endDate).after(cal.getTime())) {
                lDate.add(sdf.format(cal.getTime()));
            } else {
                break;
            }
        }
        // 把结束时间加入集合
        lDate.add(endDate);
        return lDate;

    }
}
